#ifndef PSD_SESSION_H
#define PSD_SESSION_H

#include "config.h"

#include <pthread.h>

#include "queue.h"

#include "libxsp.h"
#include "xsp-proto.h"
#include "psd_settings.h"

#define PSD_BUF_SIZE	     1048576

typedef struct psd_session_t {
	char id[2*XSP_SESSIONID_LEN + 1];

	xspHop **child;
	int child_count;

	char *user;

	psdSettings *requested_settings;

	xspHop *next_hop_info;

	LIST_HEAD(sess_pc_listhead, psd_connection_t) parent_conns;
	LIST_HEAD(sess_cc_listhead, psd_connection_t) child_conns;

	LIST_HEAD(sess_pdc_listhead, psd_connection_t) parent_data_conns;
        LIST_HEAD(sess_cdc_listhead, psd_connection_t) child_data_conns;

	struct psd_credentials_t *credentials;

	struct timeval start_time, end_time;

	int references;
	pthread_mutex_t references_lock;

	LIST_ENTRY(psd_session_t) sess_list;

#ifdef NETLOGGER
        int nl_id;
#endif
} psdSess;


int psd_sessions_init();

int psd_setup_session(psdSess *sess, char ***error_msgs);
void psd_end_session(psdSess *sess);
psdSess *psd_convert_xspSess(xspSess *old_sess);
psdSess *psd_alloc_sess();

psdSess **psd_get_sessions(int *count);

inline char *psd_session_get_id(psdSess *sess);
inline char *psd_session_get_user(psdSess *sess);
inline void psd_session_set_user(psdSess *sess, char *user);
inline void psd_session_close_connections(psdSess *sess);
void psd_free_session(psdSess *sess);
psdSess *psd_session_get_ref(psdSess *sess);
psdSess *__psd_session_get_ref(psdSess *sess);
void psd_session_put_ref(psdSess *sess);
int psd_num_sessions();
int psd_session_get_stat(psdSess *sess, uint16_t type, void *optval, size_t *optlen);
int psd_session_main_loop(psdSess *sess);
void psd_session_finalize(psdSess *sess);

#include "psd_listener.h"

void *psd_default_handle_conn(void *arg);

#ifdef NETLOGGER
int get_next_stream_id();
#endif

#endif
